home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dtl / dv2dt.c < prev    next >
C/C++ Source or Header  |  1995-02-09  |  19KB  |  912 lines

  1. /* dv2dt - convert DVI file to human-readable "DTL" format.
  2.    - (ANSI C) version 0.5.1 - 19:09 GMT +11  Thu 9 Feb 1995
  3.    - author:  Geoffrey Tobin    ecsgrt@luxor.latrobe.edu.au
  4.    - patch:  Michal Tomczak-Jaegermann   ntomczak@vm.ucs.ualberta.ca
  5.    - Reference:  "The DVI Driver Standard, Level 0",
  6.                  by  The TUG DVI Driver Standards Committee.
  7.                  Appendix A, "Device-Independent File Format".
  8. */
  9.  
  10. /* unix version; read from stdin, write to stdout, by default. */
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16.  
  17. #include "dtl.h"
  18.  
  19. #define PRINT_BCOM   if (group) fprintf (dtl, "%s", BCOM)
  20. #define PRINT_ECOM   if (group) fprintf (dtl, "%s", ECOM)
  21.  
  22. /*
  23.   operation's:
  24.      opcode,
  25.      name,
  26.      number of args,
  27.      string of arguments.
  28. */
  29. struct op_info_st {int code; char * name; int nargs; char * args; };
  30.  
  31. typedef  struct op_info_st  op_info;
  32.  
  33. /*
  34.   table's:
  35.      name,
  36.      first opcode,
  37.      last opcode,
  38.      pointer to opcode info.
  39. */
  40. struct op_table_st {char * name; int first; int last; op_info * list; };
  41.  
  42. typedef  struct op_table_st  op_table;
  43.  
  44. /* Table for opcodes 128 to 170 inclusive. */
  45.  
  46. op_info  op_info_128_170 [] =
  47. {
  48.   {128, "s1", 1, "1"},
  49.   {129, "s2", 1, "2"},
  50.   {130, "s3", 1, "3"},
  51.   {131, "s4", 1, "-4"},
  52.   {132, "sr", 2, "-4 -4"},
  53.   {133, "p1", 1, "1"},
  54.   {134, "p2", 1, "2"},
  55.   {135, "p3", 1, "3"},
  56.   {136, "p4", 1, "-4"},
  57.   {137, "pr", 2, "-4 -4"},
  58.   {138, "nop", 0, ""},
  59.   {139, "bop", 11, "-4 -4 -4 -4 -4 -4 -4 -4 -4 -4 -4"},
  60.   {140, "eop", 0, ""},
  61.   {141, "[", 0, ""},
  62.   {142, "]", 0, ""},
  63.   {143, "r1", 1, "-1"},
  64.   {144, "r2", 1, "-2"},
  65.   {145, "r3", 1, "-3"},
  66.   {146, "r4", 1, "-4"},
  67.   {147, "w0", 0, ""},
  68.   {148, "w1", 1, "-1"},
  69.   {149, "w2", 1, "-2"},
  70.   {150, "w3", 1, "-3"},
  71.   {151, "w4", 1, "-4"},
  72.   {152, "x0", 0, ""},
  73.   {153, "x1", 1, "-1"},
  74.   {154, "x2", 1, "-2"},
  75.   {155, "x3", 1, "-3"},
  76.   {156, "x4", 1, "-4"},
  77.   {157, "d1", 1, "-1"},
  78.   {158, "d2", 1, "-2"},
  79.   {159, "d3", 1, "-3"},
  80.   {160, "d4", 1, "-4"},
  81.   {161, "y0", 0, ""},
  82.   {162, "y1", 1, "-1"},
  83.   {163, "y2", 1, "-2"},
  84.   {164, "y3", 1, "-3"},
  85.   {165, "y4", 1, "-4"},
  86.   {166, "z0", 0, ""},
  87.   {167, "z1", 1, "-1"},
  88.   {168, "z2", 1, "-2"},
  89.   {169, "z3", 1, "-3"},
  90.   {170, "z4", 1, "-4"}
  91. };  /* op_info  op_info_128_170 [] */
  92.  
  93. op_table  op_128_170  =  {"op_128_170", 128, 170, op_info_128_170};
  94.  
  95. /* Table for font with 1 to 4 bytes (opcodes 235 to 238) inclusive. */
  96.  
  97. op_info  fnt_n [] =
  98. {
  99.   {235, "f1", 1, "1"},
  100.   {236, "f2", 1, "2"},
  101.   {237, "f3", 1, "3"},
  102.   {238, "f4", 1, "-4"}
  103. };  /* op_info  fnt_n [] */
  104.  
  105. op_table  fnt  =  {"f", 235, 238, fnt_n};
  106.  
  107.  
  108. /* function prototypes */
  109.  
  110. int open_dvi __((char * dvi_file, FILE ** dvi));
  111. int open_dtl __((char * dtl_file, FILE ** dtl));
  112. int dv2dt __((FILE * dvi, FILE * dtl));
  113.  
  114. COUNT wunsigned __((int n,  FILE * dvi,  FILE * dtl));
  115. COUNT wsigned   __((int n,  FILE * dvi,  FILE * dtl));
  116. S4 rsigned   __((int n,  FILE * dvi));
  117. U4 runsigned __((int n,  FILE * dvi));
  118.  
  119. COUNT wtable __((op_table table, int opcode, FILE * dvi, FILE * dtl));
  120.  
  121. COUNT setseq __((int opcode, FILE * dvi, FILE * dtl));
  122. Void setpchar __((int charcode, FILE * dtl));
  123.  
  124. COUNT special __((FILE * dvi,  FILE * dtl,  int n));
  125. COUNT fontdef __((FILE * dvi,  FILE * dtl,  int n));
  126. COUNT preamble  __((FILE * dvi,  FILE * dtl));
  127. COUNT postamble __((FILE * dvi,  FILE * dtl));
  128. COUNT postpost  __((FILE * dvi,  FILE * dtl));
  129.  
  130.  
  131. String program;  /* name of dv2dt program */
  132.  
  133. int
  134. main
  135. #ifdef __STDC__
  136.   (int argc,  char * argv[])
  137. #else
  138.   (argc, argv)
  139.   int argc;
  140.   char * argv[];
  141. #endif
  142. {
  143.   FILE * dvi = stdin;
  144.   FILE * dtl = stdout;
  145.  
  146.   /* Watch out:  C's standard library's string functions are dicey */
  147.   strncpy (program, argv[0], MAXSTRLEN);
  148.  
  149.   if (argc > 1)
  150.     open_dvi (argv[1], &dvi);
  151.  
  152.   if (argc > 2)
  153.     open_dtl (argv[2], &dtl);
  154.  
  155.   dv2dt (dvi, dtl);
  156.  
  157.   return 0;  /* OK */
  158. }
  159. /* end main */
  160.  
  161. int
  162. open_dvi
  163. #ifdef __STDC__
  164.   (char * dvi_file, FILE ** pdvi)
  165. #else
  166.   (dvi_file, pdvi)
  167.   char * dvi_file;
  168.   FILE ** pdvi;
  169. #endif
  170. /* I:  dvi_file;  I:  pdvi;  O:  *pdvi. */
  171. {
  172.   if (pdvi == NULL)
  173.   {
  174.     fprintf (stderr, "%s:  address of dvi variable is NULL.\n", program);
  175.     exit (1);
  176.   }
  177.  
  178.   *pdvi = fopen (dvi_file, "rb");
  179.  
  180.   if (*pdvi == NULL)
  181.   {
  182.     fprintf (stderr, "%s:  Cannot open \"%s\" for binary reading.\n",
  183.       program, dvi_file);
  184.     exit (1);
  185.   }
  186.  
  187.   return 1;  /* OK */
  188. }
  189. /* open_dvi */
  190.  
  191. int
  192. open_dtl
  193. #ifdef __STDC__
  194.   (char * dtl_file, FILE ** pdtl)
  195. #else
  196.   (dtl_file, pdtl)
  197.   char * dtl_file;
  198.   FILE ** pdtl;
  199. #endif
  200. /* I:  dtl_file;  I:  pdtl;  O:  *pdtl. */
  201. {
  202.   if (pdtl == NULL)
  203.   {
  204.     fprintf (stderr, "%s:  address of dtl variable is NULL.\n", program);
  205.     exit (1);
  206.   }
  207.  
  208.   *pdtl = fopen (dtl_file, "w");
  209.  
  210.   if (*pdtl == NULL)
  211.   {
  212.     fprintf (stderr, "%s:  Cannot open \"%s\" for text writing.\n",
  213.       program, dtl_file);
  214.     exit (1);
  215.   }
  216.  
  217.   return 1;  /* OK */
  218. }
  219. /* open_dtl */
  220.  
  221. int
  222. dv2dt
  223. #ifdef __STDC__
  224.   (FILE * dvi, FILE * dtl)
  225. #else
  226.   (dvi, dtl)
  227.   FILE * dvi;
  228.   FILE * dtl;
  229. #endif
  230. {
  231.   int opcode;
  232.   COUNT count;  /* intended to count bytes to DVI file; as yet unused. */
  233.  
  234.   PRINT_BCOM;
  235.   fprintf (dtl, "variety ");
  236. /*  fprintf (dtl, BMES); */
  237.   fprintf (dtl, VARIETY);
  238. /*  fprintf (dtl, EMES); */
  239.   PRINT_ECOM;
  240.   fprintf (dtl, "\n");
  241.  
  242.   /* start counting DVI bytes */
  243.   count = 0;
  244.   while ((opcode = fgetc (dvi)) != EOF)
  245.   {
  246.     PRINT_BCOM;  /* start of command and parameters */
  247.     if (opcode < 0 || opcode > 255)
  248.     {
  249.       count += 1;
  250.       fprintf (stderr, "%s:  Non-byte from \"fgetc()\"!\n", program);
  251.       exit (1);
  252.     }
  253.     else if (opcode <= 127)
  254.     {
  255.       /* setchar commands */
  256.       /* count += 1; */
  257.       /* fprintf (dtl, "%s%d", SETCHAR, opcode); */
  258.       count +=
  259.       setseq (opcode, dvi, dtl);
  260.     }
  261.     else if (opcode >= 128 && opcode <= 170)
  262.     {
  263.       count +=
  264.       wtable (op_128_170, opcode, dvi, dtl);
  265.     }
  266.     else if (opcode >= 171 && opcode <= 234)
  267.     {
  268.       count += 1;
  269.       fprintf (dtl, "%s%d", FONTNUM, opcode - 171);
  270.     }
  271.     else if (opcode >= 235 && opcode <= 238)
  272.     {
  273.       count +=
  274.       wtable (fnt, opcode, dvi, dtl);
  275.     }
  276.     else if (opcode >= 239 && opcode <= 242)
  277.     {
  278.       count +=
  279.       special (dvi, dtl, opcode - 238);
  280.     }
  281.     else if (opcode >= 243 && opcode <= 246)
  282.     {
  283.       count +=
  284.       fontdef (dvi, dtl, opcode - 242);
  285.     }
  286.     else if (opcode == 247)
  287.     {
  288.       count +=
  289.       preamble (dvi, dtl);
  290.     }
  291.     else if (opcode == 248)
  292.     {
  293.       count +=
  294.       postamble (dvi, dtl);
  295.     }
  296.     else if (opcode == 249)
  297.     {
  298.       count +=
  299.       postpost (dvi, dtl);
  300.     }
  301.     else if (opcode >= 250 && opcode <= 255)
  302.     {
  303.       count += 1;
  304.       fprintf (dtl, "opcode%d", opcode);
  305.     }
  306.     else
  307.     {
  308.       count += 1;
  309.       fprintf (stderr, "%s:  unknown byte.\n", program);
  310.       exit (1);
  311.     }
  312.     PRINT_ECOM;  /* end of command and parameters */
  313.     fprintf (dtl, "\n");
  314.     if (fflush (dtl) == EOF)
  315.     {
  316.       fprintf (stderr, "%s:  fflush on dtl file gave write error!\n", program);
  317.       exit (1);
  318.     }
  319.   } /* end while */
  320.  
  321.   return 1;  /* OK */
  322. }
  323. /* dv2dt */
  324.  
  325.  
  326. COUNT
  327. wunsigned
  328. #ifdef __STDC__
  329.   (int n, FILE * dvi, FILE * dtl)
  330. #else
  331.   (n, dvi, dtl)
  332.   int n;
  333.   FILE * dvi;
  334.   FILE * dtl;
  335. #endif
  336. {
  337.   U4 unum;
  338.  
  339.   fprintf (dtl, " ");
  340.   unum = runsigned (n, dvi);
  341.   fprintf (dtl, UF4, unum);
  342.   return n;
  343. }
  344. /* end wunsigned */
  345.  
  346. COUNT
  347. wsigned
  348. #ifdef __STDC__
  349.   (int n, FILE * dvi, FILE * dtl)
  350. #else
  351.   (n, dvi, dtl)
  352.   int n;
  353.   FILE * dvi;
  354.   FILE * dtl;
  355. #endif
  356. {
  357.   S4 snum;
  358.  
  359.   fprintf (dtl, " ");
  360.   snum = rsigned (n, dvi);
  361.   fprintf (dtl, SF4, snum);
  362.   return n;
  363. }
  364. /* end wsigned */
  365.  
  366. U4
  367. runsigned
  368. #ifdef __STDC__
  369.   (int n,  FILE * dvi)
  370. #else
  371.   (n, dvi)
  372.   int n;
  373.   FILE * dvi;
  374. #endif
  375. /* read 1 <= n <= 4 bytes for an unsigned integer from dvi file */
  376. /* DVI format uses Big-endian storage of numbers. */
  377. {
  378.   U4 integer;
  379.   int ibyte = 0;
  380.   int i;
  381.  
  382.   if (n < 1 || n > 4)
  383.   {
  384.     fprintf (stderr,
  385.       "%s:  runsigned() asked for %d bytes.  Must be 1 to 4.\n", program, n);
  386.     exit (1);
  387.   }
  388.  
  389.   /* Following calculation works iff storage is big-endian. */
  390.   integer = 0;
  391.   for (i = 0; i < n; i++)
  392.   {
  393.     integer *= 256;
  394.     ibyte = fgetc (dvi);
  395.     integer += ibyte;
  396.   }
  397.  
  398.   return integer;
  399. }
  400. /* end runsigned */
  401.  
  402. S4
  403. rsigned
  404. #ifdef __STDC__
  405.   (int n,  FILE * dvi)
  406. #else
  407.   (n, dvi)
  408.   int n;
  409.   FILE * dvi;
  410. #endif
  411. /* read 1 <= n <= 4 bytes for a signed integer from dvi file */
  412. /* DVI format uses Big-endian storage of numbers. */
  413. {
  414.   S4 integer;
  415.   int ibyte = 0;
  416.   int i;
  417.  
  418.   if (n < 1 || n > 4)
  419.   {
  420.     fprintf (stderr,
  421.       "%s:  rsigned() asked for %d bytes.  Must be 1 to 4.\n", program, n);
  422.     exit (1);
  423.   }
  424.  
  425.   /* Following calculation works iff storage is big-endian. */
  426.   integer = 0;
  427.   for (i = 0; i < n; i++)
  428.   {
  429.     integer *= 256;
  430.     ibyte = fgetc (dvi);
  431.     /* Big-endian implies sign byte is first byte. */
  432.     if (i == 0 && ibyte >= 128)
  433.     {
  434.       ibyte -= 256;
  435.     }
  436.     integer += ibyte;
  437.   }
  438.  
  439.   return integer;
  440. }
  441. /* end rsigned */
  442.  
  443. COUNT
  444. wtable
  445. #ifdef __STDC__
  446.   (op_table table, int opcode, FILE * dvi, FILE * dtl)
  447. #else
  448.   (table, opcode, dvi, dtl)
  449.   op_table table;
  450.   int opcode;
  451.   FILE * dvi;
  452.   FILE * dtl;
  453. #endif
  454. /* write command with given opcode in given table */
  455. /* return number of DVI bytes in this command */
  456. {
  457.   op_info op;  /* pointer into table of operations and arguments */
  458.   COUNT bcount = 0;  /* number of bytes in arguments of this opcode */
  459.   String args;  /* arguments string */
  460.   int i;  /* count of arguments read from args */
  461.   int pos;  /* position in args */
  462.  
  463.   /* Defensive programming. */
  464.   if (opcode < table.first || opcode > table.last)
  465.   {
  466.     fprintf (stderr,
  467.       "%s: opcode %d is outside table %s [ %d to %d ] !\n",
  468.       program, opcode, table.name, table.first, table.last);
  469.     exit (1);
  470.   }
  471.  
  472.   op = table.list [opcode - table.first];
  473.  
  474.   /* Further defensive programming. */
  475.   if (op.code != opcode)
  476.   {
  477.     fprintf (stderr, "%s: internal table %s wrong!\n", program, table.name);
  478.     exit (1);
  479.   }
  480.  
  481.   bcount = 1;
  482.   fprintf (dtl, "%s", op.name);
  483.  
  484.   /* NB:  sscanf does an ungetc, */
  485.   /*      so args must be writable. */
  486.  
  487.   strncpy (args, op.args, MAXSTRLEN);
  488.  
  489.   pos = 0;
  490.   for (i = 0; i < op.nargs; i++)
  491.   {
  492.     int argtype;  /* sign and number of bytes in current argument */
  493.     int nconv;  /* number of successful conversions from args */
  494.     int nread;  /* number of bytes read from args */
  495.  
  496.     nconv = sscanf (args + pos, "%d%n", &argtype, &nread);
  497.  
  498.     /* internal consistency checks */
  499.     if (nconv != 1 || nread <= 0)
  500.     {
  501.       fprintf (stderr,
  502.         "%s: internal read of table %s failed!\n", program, table.name);
  503.       exit (1);
  504.     }
  505.  
  506.     pos += nread;
  507.  
  508.     bcount += ( argtype < 0 ?
  509.                wsigned  (-argtype, dvi, dtl) :
  510.                wunsigned (argtype, dvi, dtl)  ) ;
  511.   } /* end for */
  512.  
  513.   return bcount;
  514.  
  515. }
  516. /* wtable */
  517.  
  518. COUNT
  519. setseq
  520. #ifdef __STDC__
  521.   (int opcode, FILE * dvi, FILE * dtl)
  522. #else
  523.   (opcode, dvi, dtl)
  524.   int opcode;
  525.   FILE * dvi;
  526.   FILE * dtl;
  527. #endif
  528. /* write a sequence of setchar commands */
  529. /* return count of DVI bytes interpreted into DTL */
  530. {
  531.   int charcode = opcode;  /* fortuitous */
  532.   int ccount = 0;
  533.  
  534.   if (!isprint (charcode))
  535.   {
  536.     ccount = 1;
  537.     fprintf (dtl, "%s%02X", SETCHAR, opcode);
  538.   }
  539.   else
  540.   {
  541.     /* start of sequence of font characters */
  542.     fprintf (dtl, BSEQ);
  543.  
  544.     /* first character */
  545.     ccount = 1;
  546.     setpchar (charcode, dtl);
  547.  
  548.     /* subsequent characters */
  549.     while ((opcode = fgetc (dvi)) != EOF)
  550.     {
  551.       if (opcode < 0 || opcode > 127)
  552.       {
  553.         break;  /* not a setchar command, so sequence has ended */
  554.       }
  555.       charcode = opcode;  /* fortuitous */
  556.       if (!isprint (charcode))  /* not printable ascii */
  557.       {
  558.         break;  /* end of font character sequence, as for other commands */
  559.       }
  560.       else  /* printable ASCII */
  561.       {
  562.         ccount += 1;
  563.         setpchar (charcode, dtl);
  564.       }
  565.     }  /* end for loop */
  566.  
  567.     /* prepare to reread opcode of next DVI command */
  568.     if (ungetc (opcode, dvi) == EOF)
  569.     {
  570.       fprintf (stderr, "setseq:  cannot push back a byte\n");
  571.       exit (1);
  572.     }
  573.  
  574.     /* end of sequence of font characters */
  575.     fprintf (dtl, ESEQ);
  576.   }
  577.   return ccount;
  578. }
  579. /* setseq */
  580.  
  581. Void
  582. setpchar
  583. #ifdef __STDC__
  584.   (int charcode, FILE * dtl)
  585. #else
  586.   (charcode, dtl)
  587.   int charcode;
  588.   FILE * dtl;
  589. #endif
  590. /* set printable character */
  591. {
  592.   switch (charcode)
  593.   {
  594.     case ESC_CHAR:
  595.       fprintf (dtl, "%c", ESC_CHAR);
  596.       fprintf (dtl, "%c", ESC_CHAR);
  597.       break;
  598.     case QUOTE_CHAR:
  599.       fprintf (dtl, "%c", ESC_CHAR);
  600.       fprintf (dtl, "%c", QUOTE_CHAR);
  601.       break;
  602.     case BSEQ_CHAR:
  603.       fprintf (dtl, "%c", ESC_CHAR);
  604.       fprintf (dtl, "%c", BSEQ_CHAR);
  605.       break;
  606.     case ESEQ_CHAR:
  607.       fprintf (dtl, "%c", ESC_CHAR);
  608.       fprintf (dtl, "%c", ESEQ_CHAR);
  609.       break;
  610.     default:
  611.       fprintf (dtl, "%c", charcode);
  612.       break;
  613.   }
  614. }
  615. /* setpchar */
  616.  
  617. COUNT
  618. special
  619. #ifdef __STDC__
  620.   (FILE * dvi,  FILE * dtl,  int n)
  621. #else
  622.   (dvi, dtl, n)
  623.   FILE * dvi;
  624.   FILE * dtl;
  625.   int n;
  626. #endif
  627. /* read special 1 .. 4 from dvi and write in dtl */
  628. /* return number of DVI bytes interpreted into DTL */
  629. {
  630.   U4  k;
  631.   int i, ch;
  632.  
  633.   if (n < 1 || n > 4)
  634.   {
  635.     fprintf (stderr, "%s:  special %d, range is 1 to 4.\n", program, n);
  636.     exit (1);
  637.   }
  638.  
  639.   fprintf (dtl, "%s%d", SPECIAL, n);
  640.  
  641.   /* k[n] = length of special string */
  642.   fprintf (dtl, " ");
  643.   k = runsigned (n, dvi);
  644.   fprintf (dtl, UF4, k);
  645.  
  646.   /* x[k] = special string */
  647.  
  648.   fprintf (dtl, " ");
  649.   fprintf (dtl, "'");
  650.   for (i=0; i < k; i++)
  651.   {
  652.     ch = fgetc (dvi);
  653.     fprintf (dtl, "%c", ch);
  654.   }
  655.   fprintf (dtl, "'");
  656.  
  657.   return (1 + n + k);
  658. }
  659. /* end special */
  660.  
  661. COUNT
  662. fontdef
  663. #ifdef __STDC__
  664.   (FILE * dvi,  FILE * dtl,  int n)
  665. #else
  666.   (dvi,  dtl,  n)
  667.   FILE * dvi;
  668.   FILE * dtl;
  669.   int n;
  670. #endif
  671. /* read fontdef 1 .. 4 from dvi and write in dtl */
  672. /* return number of DVI bytes interpreted into DTL */
  673. {
  674.   U4 ku, c, s, d, a, l;
  675.   S4 ks;
  676.   int i, ch;
  677.  
  678.   if (n < 1 || n > 4)
  679.   {
  680.     fprintf (stderr, "%s:  font def %d, range is 1 to 4.\n", program, n);
  681.     exit (1);
  682.   }
  683.  
  684.   fprintf (dtl, "%s%d", FONTDEF, n);
  685.  
  686.   /* k[n] = font number */
  687.   fprintf (dtl, " ");
  688.   if (n == 4)
  689.   {
  690.     ks = rsigned (n, dvi);
  691.     fprintf (dtl, SF4, ks);
  692.   }
  693.   else
  694.   {
  695.     ku = runsigned (n, dvi);
  696.     fprintf (dtl, UF4, ku);
  697.   }
  698.  
  699.   /* c[4] = checksum */
  700.   fprintf (dtl, " ");
  701.   c = runsigned (4, dvi);
  702. /*  fprintf (dtl, XF4, c); */
  703.   /* write in octal, to allow quick comparison with tftopl's output */
  704.   fprintf (dtl, OF4, c);
  705.  
  706.   /* s[4] = scale factor */
  707.   fprintf (dtl, " ");
  708.   s = runsigned (4, dvi);
  709.   fprintf (dtl, UF4, s);
  710.  
  711.   /* d[4] = design size */
  712.   fprintf (dtl, " ");
  713.   d = runsigned (4, dvi);
  714.   fprintf (dtl, UF4, d);
  715.  
  716.   /* a[1] = length of area (directory) name */
  717.   fprintf (dtl, " ");
  718.   a = runsigned (1, dvi);
  719.   fprintf (dtl, UF4, a);
  720.  
  721.   /* l[1] = length of font name */
  722.   fprintf (dtl, " ");
  723.   l = runsigned (1, dvi);
  724.   fprintf (dtl, UF4, l);
  725.  
  726.   /* n[a+l] = font pathname = area (directory) + font */
  727.  
  728.   fprintf (dtl, " ");
  729.   fprintf (dtl, "'");
  730.   for (i=0; i < a+l; i++)
  731.   {
  732.     ch = fgetc (dvi);
  733.     fprintf (dtl, "%c", ch);
  734.   }
  735.   fprintf (dtl, "'");
  736.  
  737.   return (1 + n + 4 + 4 + 4 + 1 + 1 + a + l);
  738. }
  739. /* end fontdef */
  740.  
  741. COUNT
  742. preamble
  743. #ifdef __STDC__
  744.   (FILE * dvi,  FILE * dtl)
  745. #else
  746.   (dvi,  dtl)
  747.   FILE * dvi;
  748.   FILE * dtl;
  749. #endif
  750. /* read preamble from dvi and write in dtl */
  751. /* return number of DVI bytes interpreted into DTL */
  752. {
  753.   U4 id, num, den, mag, k;
  754.   int i, ch;
  755.  
  756.   fprintf (dtl, "pre");
  757.  
  758.   /* i[1] = DVI format identification */
  759.   fprintf (dtl, " ");
  760.   id = runsigned (1, dvi);
  761.   fprintf (dtl, UF4, id);
  762.  
  763.   /* num[4] = numerator of DVI unit */
  764.   fprintf (dtl, " ");
  765.   num = runsigned (4, dvi);
  766.   fprintf (dtl, UF4, num);
  767.  
  768.   /* den[4] = denominator of DVI unit */
  769.   fprintf (dtl, " ");
  770.   den = runsigned (4, dvi);
  771.   fprintf (dtl, UF4, den);
  772.  
  773.   /* mag[4] = 1000 x magnification */
  774.   fprintf (dtl, " ");
  775.   mag = runsigned (4, dvi);
  776.   fprintf (dtl, UF4, mag);
  777.  
  778.   /* k[1] = length of comment */
  779.   fprintf (dtl, " ");
  780.   k = runsigned (1, dvi);
  781.   fprintf (dtl, UF4, k);
  782.  
  783.   /* x[k] = comment string */
  784.  
  785.   fprintf (dtl, " ");
  786.   fprintf (dtl, "'");
  787.   for (i=0; i < k; i++)
  788.   {
  789.     ch = fgetc (dvi);
  790.     fprintf (dtl, "%c", ch);
  791.   }
  792.   fprintf (dtl, "'");
  793.  
  794.   return (1 + 1 + 4 + 4 + 4 + 1 + k);
  795. }
  796. /* end preamble */
  797.  
  798. COUNT
  799. postamble
  800. #ifdef __STDC__
  801.   (FILE * dvi,  FILE * dtl)
  802. #else
  803.   (dvi,  dtl)
  804.   FILE * dvi;
  805.   FILE * dtl;
  806. #endif
  807. /* read postamble from dvi and write in dtl */
  808. /* return number of bytes */
  809. {
  810.   U4 p, num, den, mag, l, u, s, t;
  811.  
  812.   fprintf (dtl, "post");
  813.  
  814.   /* p[4] = pointer to final bop */
  815.   fprintf (dtl, " ");
  816.   p = runsigned (4, dvi);
  817.   fprintf (dtl, UF4, p);
  818.  
  819.   /* num[4] = numerator of DVI unit */
  820.   fprintf (dtl, " ");
  821.   num = runsigned (4, dvi);
  822.   fprintf (dtl, UF4, num);
  823.  
  824.   /* den[4] = denominator of DVI unit */
  825.   fprintf (dtl, " ");
  826.   den = runsigned (4, dvi);
  827.   fprintf (dtl, UF4, den);
  828.  
  829.   /* mag[4] = 1000 x magnification */
  830.   fprintf (dtl, " ");
  831.   mag = runsigned (4, dvi);
  832.   fprintf (dtl, UF4, mag);
  833.  
  834.   /* l[4] = height + depth of tallest page */
  835.   fprintf (dtl, " ");
  836.   l = runsigned (4, dvi);
  837.   fprintf (dtl, UF4, l);
  838.  
  839.   /* u[4] = width of widest page */
  840.   fprintf (dtl, " ");
  841.   u = runsigned (4, dvi);
  842.   fprintf (dtl, UF4, u);
  843.  
  844.   /* s[2] = maximum stack depth */
  845.   fprintf (dtl, " ");
  846.   s = runsigned (2, dvi);
  847.   fprintf (dtl, UF4, s);
  848.  
  849.   /* t[2] = total number of pages (bop commands) */
  850.   fprintf (dtl, " ");
  851.   t = runsigned (2, dvi);
  852.   fprintf (dtl, UF4, t);
  853.  
  854. /*  return (29);  */
  855.   return (1 + 4 + 4 + 4 + 4 + 4 + 4 + 2 + 2);
  856. }
  857. /* end postamble */
  858.  
  859. COUNT
  860. postpost
  861. #ifdef __STDC__
  862.   (FILE * dvi,  FILE * dtl)
  863. #else
  864.   (dvi,  dtl)
  865.   FILE * dvi;
  866.   FILE * dtl;
  867. #endif
  868. /* read post_post from dvi and write in dtl */
  869. /* return number of bytes */
  870. {
  871.   U4 q, id;
  872.   int b223;  /* hope this is 8-bit clean */
  873.   int n223;  /* number of "223" bytes in final padding */
  874.  
  875.   fprintf (dtl, "post_post");
  876.  
  877.   /* q[4] = pointer to post command */
  878.   fprintf (dtl, " ");
  879.   q = runsigned (4, dvi);
  880.   fprintf (dtl, UF4, q);
  881.  
  882.   /* i[1] = DVI identification byte */
  883.   fprintf (dtl, " ");
  884.   id = runsigned (1, dvi);
  885.   fprintf (dtl, UF4, id);
  886.  
  887.   /* final padding by "223" bytes */
  888.   /* hope this way of obtaining b223 is 8-bit clean */
  889.   for (n223 = 0; (b223 = fgetc (dvi)) == 223; n223++)
  890.   {
  891.     fprintf (dtl, " ");
  892.     fprintf (dtl, "%d", 223);
  893.   }
  894.   if (n223 < 4)
  895.   {
  896.     fprintf (stderr,
  897.       "%s:  bad post_post:  fewer than four \"223\" bytes.\n", program);
  898.     exit (1);
  899.   }
  900.   if (b223 != EOF)
  901.   {
  902.     fprintf (stderr,
  903.       "%s:  bad post_post:  doesn't end with a \"223\".\n", program);
  904.     exit (1);
  905.   }
  906.  
  907.   return (1 + 4 + 1 + n223);
  908. }
  909. /* end postpost */
  910.  
  911. /* end of "dv2dt.c" */
  912.